#include <sys/socket.h>
#include <netinet/in.h>

#include "ClientManager.h"

#include "err.h"

#include "debug.h"

session_mgr::ClientManager::ClientManager(session_mgr::ClientConnection const clients[], int clients_count):
clientfd(),
connections(clients, clients + clients_count)
{
    try
    {
        debug("Connecting %i client servers...\n", clients_count);
        for(int i = 0; i < clients_count; ++i)
        {
            clientfd.push_back(socket(AF_INET, SOCK_STREAM, 0));
            if(clientfd[i] < 0)
                lib_err(socket);
            sockaddr_in addr;
            addr.sin_family = AF_INET;
            addr.sin_addr.s_addr = htonl(clients[i].ipv4addr);
            addr.sin_port = htons(clients[i].port);
            safe_call(connect, clientfd[i], (sockaddr*)&addr, sizeof(addr));
            uint8_t const one = 1;
            ssize_t nwrite;
            if(nwrite = write(clientfd[i], &one, 1), nwrite != 1)
                app_error("write unexpectedly returned %zu instead of 1.", nwrite);
            ssize_t nread;
            uint16_t port;
            if(nread = read(clientfd[i], &port, 2), nread != 2)
                app_error("read unexpectedly returned %zu instead of 2.", nread);
            connections[i].port = ntohs(port);
        }
    }
    catch(...)
    {
        for(size_t i = 0; i < clientfd.size(); ++i)
            close(clientfd[i]);
        throw;
    }
}

session_mgr::ClientManager::~ClientManager()
{
    for(size_t i = 0; i < clientfd.size(); ++i)
        close(clientfd[i]);
}

std::vector< session_mgr::ClientConnection > const& session_mgr::ClientManager::getConnections() const
{
    return connections;
}
